import * as React from 'react';

interface IProps {
    load: any;
    children: any;
}

interface State {
    mod: any
}

const initialState: State = {
    mod: null
};

type IState = Readonly<typeof initialState>;

class Bundle extends React.Component<IProps, IState> {
    readonly state: IState = initialState

    cancelablePromise:{ promise: Promise<{}>; cancel(): void; }

    makeCancelable = (promise: Promise<{}>) => {
        let hasCanceled_ = false;
        const wrappedPromise = new Promise((resolve, reject) => {
            promise.then(
                val => hasCanceled_ ? reject({ isCanceled: true }) : resolve(val),
                error => hasCanceled_ ? reject({ isCanceled: true }) : reject(error)
            );
        });
        return {
            promise: wrappedPromise,
            cancel() {
                hasCanceled_ = true;
            },
        };
    };

    componentWillMount() {
        let _this = this;
        this.cancelablePromise = this.makeCancelable(new Promise(resolve=> resolve()))

        this.cancelablePromise
            .promise
            .then(() => _this.load(_this.props))
            .catch((reason) => {});
    }

    componentWillReceiveProps(nextProps: IProps) {
        if (nextProps.load !== this.props.load) {
            this.load(nextProps);
        }
    }
    // load 方法，用于更新 mod 状态
    load = (props: IProps) => {
        // 初始化
        this.setState({
            mod: null
        });
        /*
            调用传入的 load 方法，并传入一个回调函数
            这个回调函数接收 在 load 方法内部异步获取到的组件，并将其更新为 mod 
        */
        props.load((mod: any) => {
            this.setState({
                mod: mod.default ? mod.default : mod
            });
        });
    }

    componentWillUnmount() {
        this.cancelablePromise.cancel();
    }

    render() {
        /*
            将存在状态中的 mod 组件作为参数传递给当前包装组件的'子'
        */
        return this.state.mod ? this.props.children(this.state.mod) : null;
    }
}

export default Bundle;